#!/usr/bin/env python

import time
import os.path

from activist.Config import Config
from activist.DataStore import DataStore
from activist.Person import Person
from activist.Group import Group
from activist.Place import Place
from activist.Event import Event
from activist.Alias import Alias
from activist.Comment import Comment
from activist.GenericData import GenericData
from activist.EventInformation import EventInformation
from activist.MetaData import MetaDataFactory, MetaData
from activist.CommandProcessor import CommandProcessor
import activist.Place
import activist.Person
import activist.Event
import activist.Time
import activist.Category

CREATE = True
LIMIT = True
BASE = '/home/mike/projects/activist.ca/grant-data-dump/actnetdev-2005-01-15/'
if CREATE:
	CommandProcessor.loadAndProcess()

import os
joiner = os.path.join(BASE,'listing_listing.txt')
sites = os.path.join(BASE,'listing_site.txt')

spamlist = []

def wordwrap(text, width=70):
        """
        from aspn
        
        A word-wrap function that preserves existing line breaks
        and most spaces in the text. Expects that existing line
        breaks are posix newlines (\n).
        """
        return reduce(lambda line, word, width=width: '%s%s%s' %
                      (line,
                       ' \n'[(len(line)-line.rfind('\n')-1
                              + len(word.split('\n',1)[0]
                                    ) >= width)],
                       word),
                      text.split(' ')
                      )


idToSite = {}
for line in open(sites,'r').readlines():
	things = line.split('\t')
	id = things[0] + '-' + things[1]
	idToSite[id] = things[3]

join = {}
for line in open(joiner,'r').readlines():
    things = line.split('\t')
    key = things[0] + '-' + things[1]
    value = things[2] + '-' + things[3]
    relation = things[4]
    if join.has_key(key):
        join[key].append((value,relation))
    else:
        join[key] = [(value,relation)]


detail = {}
notforme = {}
unclaimed = {}

def fix(l):
	rtn = ''
	slash = False
	for x in l:
		if x == '\\':
			slash = True
			continue
		elif slash and x == '\t':
			rtn = rtn + '    '
			slash = False
		else:
			rtn = rtn + x
	return rtn

if 1:
    eat = False
    data = open(os.path.join(BASE,'listingdetail.txt'),'r').read()
    newdata = filter(lambda a: a != '\r', data)

    line = ''
    for l in newdata.split('\n'):
        if len(l.strip()) == 0: continue
        if eat:
            line = line + fix(l) + '\n'
            eat = False
            continue

        if l[-1] == '\\':
            eat = True
            line = line + fix(l[:-1]) + '\n'
            continue

        line = line + fix(l)
        things = line.split('\t')
        key = things[0] + '-' + things[1]
	if len(things) < 31:
		print things[0] + '-' + things[1]
		_exit(1)
        if things[30] == '0': things[30] = ''
        if things[31] == '0': things[31] = ''
        list =  { 'title':things[8],
                  'subtitle':things[9],
                  'url':things[10],
                  'description':things[13],#.decode('latin-1'), # "content"
		  'mime':things[14],
                  'short':things[15],#things[15].decode('latin-1'),	 
                  'notes':things[16],
		  'repeat-exception':things[19],
                  'cost':things[20],
                  'agerestriction':things[21],
		  'languages':things[22],
                  'address':things[23],
                  'person':things[24],
                  'phone0':things[25],
                  'phone1':things[26],
                  'fax':things[27],
                  'email':things[28],
                  'image_url':things[29],
                  'image_width':things[30],
                  'image_height':things[31],
		  
                  'posted_by':things[35]
                  }
	if list['email'] != '':
		if not list['email'] in spamlist:
			spamlist.append(list['email'])
	for k in list:
		if list[k] == "\\N":
			list[k] = ''
	for (k,x) in list.items():
		if x is None:
			print "BAD BAD:",k

	detail[key] = list
	if not idToSite.has_key(key):
		unclaimed[key] = list
	else:
	    if idToSite[key] == 'www' or idToSite[key] == 'calgarydollars':
		    detail[key] = list
	    else:
		    stuff = []
		    if notforme.has_key(idToSite[key]):
			    stuff = notforme[idToSite[key]]
		    else:
			    notforme[idToSite[key]] = stuff
		    #stuff.append((key,list))
		    stuff.append(key)
        line = ""


spam = open("spamfile.txt","w")
for x in spamlist:
	spam.write(str(x) + '\n')
spam.close()

for x in notforme.keys():
	print "notforme",x,len(notforme[x]),notforme[x]
print len(unclaimed),"total un-mapped posts"
    
default_person = activist.Person.Person()
default_person.create('Old Data',
		      '',
		      None,
		      '',
		      'admin@activist.ca',
		      None,
		      "I am an automatically-created person who was made responsible for imported data.",
		      False)
	

monthly = []
typemapper = {}
raw = {}
types = []
subs = []
i = 0
types = []
for line in open(os.path.join(BASE,'listing.txt'),'r').readlines():
    things = line.split('\t')
    id = things[0]+'-'+things[1]
    typemapper[id] = things[14]
    raw[things[0]+'-'+things[1]] = things
    if not things[14] in types:
	    types.append(things[14])
    if not things[15] in subs:
	    subs.append(things[15])

    if detail.has_key(id):
	    d = detail[id]
	    d['country'] = things[6]
	    d['province'] = things[7]
	    d['city'] = things[8]
	    d['date-added'] = things[17]
	    d['date-start'] = things[18]
	    d['date-end'] = things[19]
	    d['dateline'] = things[20]
	    d['time-start'] = things[21]
	    d['time-end'] = things[22]
	    d['repeat-type'] = things[23]
	    d['repeat-number'] = things[24]
	    d['repeat-period'] = things[25]
	    d['repeat-frequency'] = things[26]
	    d['repeat-day'] = things[27]
	    d['repeat-date'] = things[28]
	    d['repeat-month'] = things[29]
	    d['repeat-nextdate'] = things[30]
	    d['address'] = things[37] + '\n' + things[38]
	    d['type'] = things[14]
	    if not things[14] in types: types.append(things[14])

	    if 0:
		    if d['repeat-day'] != '':
			    print "REPEAT",d

	    d['wheelchair'] = things[31]
	    d['smoking'] = things[32]
	    d['pets'] = things[33]
	    d['signlanguage'] = things[34]
	    d['childcare'] = things[35]
	    
	    for k in d:
		    if d[k] == "\\N":
			    d[k] = ''

	    if d['repeat-period'] == 'monthly':
		    monthly.append(id)


print "TYPES:",types

people = {}
peopleById = {}
groupsById = {}

nonPeople = []
##for id in join.keys():
##	if detail.has_key(id) and join.has_key(id):
##		for (value,relation) in join[id]:
##			if relation == 'contact':


for id in detail.keys():
	if detail[id] and detail[id].has_key('type') and detail[id]['type'] == 'contact':
		value = id
		if detail.has_key(value) and isinstance(detail[value]['person'],basestring):
			d = detail[value]
			if people.has_key(d['person']):
				print "  should merge!",id
				#print people[d['person']],d
				continue

			if 1:
			    person = activist.Person.Person()
			    person.create( d['person'],
					   None, # username
					   None, # password
					   d['phone0'],
					   d['email'],
					   d['address'],
					   d['description'],
					   False )
			    people[value] = person
			    people[d['person']] = person
			    peopleById[id] = person

		else:
			print "wanted contact!",value
			nonPeople.append(value)
			if key in unclaimed:
				print "  in unclaimed"
			else:
			    for (key,thing) in notforme.items():
				    if value in thing:
					    print "  in",key

def makePersonForId(id):
	if not detail.has_key(id):
		return None
	
	d = detail[id]
	person = activist.Person.Person()
	person.create( d['person'],
		       None, # username
		       None, # password
		       [d['phone0'],d['phone1'],d['fax']],
		       d['email'],
		       d['address'],
		       d['description'],
		       False )
	peopleById[id] = person
	return person


def makeGroupForId(id):
	if detail.has_key(id) and detail[id].has_key('type') and detail[id]['type'] == 'group':
		dd = detail[id]

#		if dd['city'].lower() != 'calgary':
#			print "Group",dd['title'],"not from calgary"
#			continue
		
		name = dd['title']
		description = dd['description']
		brief = dd['short']
		url = dd['url']
		topics = []
		contacts = []
		region = 'calgary.ab.ca'
		image = None
		print "MEMBERS for",name
		if join.has_key(id):
			for (i,relat) in join[id]:
				if relat == 'contact':
					if peopleById.has_key(i):
						contacts.append(peopleById[i])
						print "  MEMBER",i,peopleById[i]
					else:
						p = makePersonForId(i)
						if not p:
							print "  MEMBER GROUP",name,"wanted",i,"but no such contact",
							if detail.has_key(i): print "DETAIL",detail[i]
							else: print
						else:
							contacts.append(p)
				else:
					print "RELAT:",relat,"not handled for group",name
		else:
			print "NO MEMBERS for",name

		group = activist.Group.Group()
		group.create( name, brief, description, url, contacts, topics, contacts, region, image, default_person)
		groupsById[id] = group
		return group


places = {}

limit = 50
events = []
missing_locations = []


for id in typemapper.keys():
	if id in monthly:
		print "MONTHLY",id
	if typemapper[id] == 'event':
		if detail.has_key(id):
			locationok = False
			location = None
			if join.has_key(id):
			    for (i,relation) in join[id]:
				    if detail.has_key(i) and relation == 'location':
					    if detail[i]['address'] != '': print "ADDRESS!",detail[i]['address']
					    dd = detail[i]
					    if dd['country'] != '' and dd['province'] != '' and dd['city'] != '':
						    location = dd['city'].lower() + '.' + dd['province'].lower() + '.' + dd['country'].lower()
						    for (where,nice) in activist.Place.LOCALES:
							    if where == location:
								    locationok = True

			if not locationok:
				print "INVALID LOCATION:",location,id
				continue

			
			d = detail[id]
			#if d['repeat-day'] != '':
			#	continue
			r = raw[id]
			if r[15] == '':
				continue
			try:
				when = activist.Time.fromImportListingDetail(d)
			except ValueError:
				when = None
			if when is None:
				continue
			print "WHEN:",when,when.format()
			access = []
			if d.has_key('signlanguage') and d['signlanguage'].lower() == 'y':
				access.append('signlanguage')
			if d.has_key('childcare') and d['childcare'].lower() == 'y':
				access.append('childcare')
			if d.has_key('smoking') and d['smoking'].lower() == 'y':
				access.append('smoking')
			if d.has_key('pets') and d['pets'].lower() == 'y':
				access.append('pets')
			if d.has_key('wheelchair') and d['wheelchair'].lower() == 'y':
				access.append('wheelchair')

			location = None
			name = None
			phone = []
			notes = None
			url = None
			address = ''
			groups = []

			contact = None
			if join.has_key(id):
			    for (i,relation) in join[id]:
				    if not detail.has_key(i) and relation == 'location':
					    missing_locations.append(i)
					    
				    if relation == 'contact':
					    if detail.has_key(i):
						    if not contact:
							    contact = [(i,detail[i])]
						    else:
							    contact.append( (i,detail[i]) )
					    else:
						    print "NO-CONTACT:",i,"for",name
				    elif relation == 'location':
					    if detail.has_key(i):
						    if detail[i]['address'] != '': print "ADDRESS!",detail[i]['address']
						    dd = detail[i]
						    if not location and dd['country'] != '' and dd['province'] != '' and dd['city'] != '':
							    location = dd['city'].lower() + '.' + dd['province'].lower() + '.' + dd['country'].lower()
						    if dd['address'] != '':
							    address = dd['address']
						    if not url and dd['url'] != '':
							    url = dd['url']
						    if not name and dd['title'] != '':
							    name = dd['title']
						    if not notes and dd['description'] != '':
							    notes = dd['notes']
						    if dd['phone0'] != '' and dd['phone0'] not in phone:
							    phone.append(dd['phone0'])
						    if dd['phone1'] != '' and dd['phone1'] not in phone:
							    phone.append(dd['phone1'])
						    if dd['fax'] != '' and dd['fax'] not in phone:
							    phone.append(dd['fax'])
					    else:
						    print "no details"
				    elif relation == 'group':
					    if groupsById.has_key(i):
						    groups.append(groupsById[i])
					    else:
						    g = makeGroupForId(i)
						    if g:
							    groups.append(g)
						    else:
							    print "WANTED_GROUP:",i,
							    if detail.has_key(i): print detail[i]
							    else: print
					    
				    else:
					    print "NO-RELATION:",relation

			else:
				print "no JOIN id:",id

			print "CONTACT:",contact
			contacts = []
			if contact:
			    for (conid,condeet) in contact:
				    if peopleById.has_key(conid):
					    contacts.append(peopleById[conid])
				    else:
					    print "NO-CONTACT",conid,condeet['title'],"not found in people for",name,
					    if conid in nonPeople: print "but they're in nonPeople!"
					    else: print 

			if location and name:
				if not notes: notes = ''
				place = activist.Place.Place()
				(a,b) = address.split('\n')
				if a.lower().strip() == name.lower().strip():
					address = b
				place.create(name, address, phone, location, notes, url)
			#print d
			p = default_person
			if isinstance(d['person'],activist.Person.Person):
				p = d['person']
			elif people.has_key(d['person'].lower()):
				p = people[d['person'].lower()]
				people[d['person'].lower()] = p
			else:
				print "NO-PERSON:",d['person']
			if p is None: p = default_person
			if len(contacts): p = contacts[0]
			if d['title'] == '':
				print "WARNING: no title for event; making one up"
				title = 'no title'
			else:
				title = d['title']
			args = (p,
				title,
				when,
				access,
				d['description'],
				d['short'],
				place,
				r[15],
				contacts )
			print "ARGS:",args
			if CREATE:
				event = activist.Event.Event()
				event.create( *args )
				event.info().approve(default_person)
				events.append(event)
				if len(groups):
					for g in groups:
						event.add_group(g)
				if LIMIT:
					limit = limit - 1
					if limit <= 0:
						break

print "MISSING locations:",missing_locations
